package org.ehe.business.bom.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.ehe.business.bom.domain.BomMaster;
import org.ehe.business.bom.domain.BomProjectRelation;
import org.ehe.business.bom.domain.dto.BomCreationRequest;
import org.ehe.business.bom.mapper.BomProjectRelationMapper;
import org.ehe.business.bom.service.BomProjectRelationService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author :zhangnn
 * @className :BomProjectRelationServiceImpl
 * @description: TODO
 * @date 2025-07-30 14:10:00
 */
@Slf4j
@Service
public class BomProjectRelationServiceImpl extends ServiceImpl<BomProjectRelationMapper, BomProjectRelation> implements BomProjectRelationService {
    /**
     * 创建BOM与项目的关联关系
     */
    @Transactional
    public void createBomProjectRelation(BomProjectRelation relation) {
        log.info("创建BOM项目关联: bomId={}, projectId={}, relationType={}",
            relation.getBomId(), relation.getProjectId(), relation.getRelationType());

        // 验证关联关系
        validateBomProjectRelation(relation);

        // 检查是否已存在相同的关联关系
        if (isRelationExists(relation.getBomId(), relation.getProjectId(), relation.getRelationType())) {
            throw new RuntimeException("该BOM与项目的关联关系已存在");
        }

        // 设置默认值
        if (relation.getPriorityLevel() == null) {
            relation.setPriorityLevel(2); // 默认中等优先级
        }

        if (relation.getEffectiveDate() == null) {
            relation.setEffectiveDate(new Date());
        }

        relation.setCreateTime(new Date());
        this.save(relation);

        log.info("BOM项目关联创建成功: relationId={}", relation.getId());
        //return relation;
    }

    /**
     * 更新BOM项目关联关系
     */
    @Transactional
    public void updateBomProjectRelation(BomProjectRelation relation) {
        log.info("更新BOM项目关联: relationId={}", relation.getId());

        validateBomProjectRelation(relation);

        relation.setUpdateTime(new Date());
        this.updateById(relation);

        log.info("BOM项目关联更新成功: relationId={}", relation.getId());
    }

    /**
     * 删除BOM项目关联关系
     */
    @Transactional
    public void deleteBomProjectRelation(Long relationId) {
        log.info("删除BOM项目关联: relationId={}", relationId);

        BomProjectRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new RuntimeException("BOM项目关联关系不存在");
        }

        this.removeById(relationId);

        log.info("BOM项目关联删除成功: relationId={}", relationId);
    }

    /**
     * 根据BOM ID查询项目关联关系
     */
    public List<BomProjectRelation> getRelationsByBomId(Long bomId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId)
            .orderBy(true, true, "priority_level", "create_time");
        return this.list(wrapper);
    }

    /**
     * 根据项目ID查询BOM关联关系
     */
    public List<BomProjectRelation> getRelationsByProjectId(Long projectId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId)
            .orderBy(true, true, "priority_level", "create_time");
        return this.list(wrapper);
    }

    /**
     * 根据关联类型查询关联关系
     */
    public List<BomProjectRelation> getRelationsByType(Integer relationType) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("relation_type", relationType)
            .orderByDesc("create_time");
        return this.list(wrapper);
    }

    /**
     * 获取项目的主要BOM关联
     */
    public List<BomProjectRelation> getPrimaryBomsByProject(Long projectId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId)
            .eq("relation_type", 1) // 主要BOM
            .isNull("expire_date") // 未失效
            .or()
            .gt("expire_date", new Date()) // 或失效日期在未来
            .orderBy(true, true, "priority_level", "effective_date");
        return this.list(wrapper);
    }

    /**
     * 获取项目的备用BOM关联
     */
    public List<BomProjectRelation> getBackupBomsByProject(Long projectId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId)
            .eq("relation_type", 2) // 备用BOM
            .isNull("expire_date")
            .or()
            .gt("expire_date", new Date())
            .orderBy(true, true, "priority_level", "effective_date");
        return this.list(wrapper);
    }

    /**
     * 获取项目的参考BOM关联
     */
    public List<BomProjectRelation> getReferenceBomsByProject(Long projectId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId)
            .eq("relation_type", 3) // 参考BOM
            .isNull("expire_date")
            .or()
            .gt("expire_date", new Date())
            .orderBy(true, true, "priority_level", "effective_date");
        return this.list(wrapper);
    }

    /**
     * 获取有效的BOM项目关联关系
     */
    public List<BomProjectRelation> getEffectiveRelations(Long bomId, Long projectId) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId)
            .eq("project_id", projectId)
            .le("effective_date", new Date()) // 生效日期小于等于当前日期
            .and(w -> w.isNull("expire_date").or().gt("expire_date", new Date())) // 未失效
            .orderBy(true, true, "priority_level", "effective_date");
        return this.list(wrapper);
    }

    /**
     * 设置BOM项目关联的优先级
     */
    @Transactional
    public void setPriority(Long relationId, Integer priorityLevel) {
        log.info("设置BOM项目关联优先级: relationId={}, priority={}", relationId, priorityLevel);

        BomProjectRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new RuntimeException("BOM项目关联关系不存在");
        }

        if (priorityLevel < 1 || priorityLevel > 3) {
            throw new RuntimeException("优先级必须在1-3之间");
        }

        relation.setPriorityLevel(priorityLevel);
        relation.setUpdateTime(new Date());
        this.updateById(relation);

        log.info("BOM项目关联优先级设置成功: relationId={}", relationId);
    }

    /**
     * 激活BOM项目关联关系
     */
    @Transactional
    public void activateRelation(Long relationId) {
        log.info("激活BOM项目关联: relationId={}", relationId);

        BomProjectRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new RuntimeException("BOM项目关联关系不存在");
        }

        Date now = new Date();
        relation.setEffectiveDate(now);
        relation.setExpireDate(null); // 清除失效日期
        relation.setUpdateTime(now);
        this.updateById(relation);

        log.info("BOM项目关联激活成功: relationId={}", relationId);
    }

    /**
     * 停用BOM项目关联关系
     */
    @Transactional
    public void deactivateRelation(Long relationId) {
        log.info("停用BOM项目关联: relationId={}", relationId);

        BomProjectRelation relation = this.getById(relationId);
        if (relation == null) {
            throw new RuntimeException("BOM项目关联关系不存在");
        }

        Date now = new Date();
        relation.setExpireDate(now);
        relation.setUpdateTime(now);
        this.updateById(relation);

        log.info("BOM项目关联停用成功: relationId={}", relationId);
    }

    /**
     * 批量设置关联关系的失效日期（项目结束时使用）
     */
    @Transactional
    public void batchExpireRelationsByProject(Long projectId, Date expireDate) {
        log.info("批量设置项目BOM关联失效日期: projectId={}, expireDate={}", projectId, expireDate);

        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("project_id", projectId)
            .isNull("expire_date"); // 只处理未失效的关联

        List<BomProjectRelation> relations = this.list(wrapper);

        for (BomProjectRelation relation : relations) {
            relation.setExpireDate(expireDate);
            relation.setUpdateTime(new Date());
            this.updateById(relation);
        }

        log.info("批量设置项目BOM关联失效日期完成，共处理{}条记录", relations.size());
    }

    /**
     * 批量设置关联关系的失效日期（BOM废弃时使用）
     */
    @Transactional
    public void batchExpireRelationsByBom(Long bomId, Date expireDate) {
        log.info("批量设置BOM项目关联失效日期: bomId={}, expireDate={}", bomId, expireDate);

        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId)
            .isNull("expire_date");

        List<BomProjectRelation> relations = this.list(wrapper);

        for (BomProjectRelation relation : relations) {
            relation.setExpireDate(expireDate);
            relation.setUpdateTime(new Date());
            this.updateById(relation);
        }

        log.info("批量设置BOM项目关联失效日期完成，共处理{}条记录", relations.size());
    }

    /**
     * 验证BOM项目关联关系
     */
    private void validateBomProjectRelation(BomProjectRelation relation) {
        if (relation.getBomId() == null) {
            throw new RuntimeException("BOM ID不能为空");
        }

        if (relation.getProjectId() == null) {
            throw new RuntimeException("项目ID不能为空");
        }

        if (relation.getRelationType() == null) {
            throw new RuntimeException("关联类型不能为空");
        }

        if (relation.getRelationType() < 1 || relation.getRelationType() > 3) {
            throw new RuntimeException("关联类型必须在1-3之间");
        }

        if (relation.getPriorityLevel() != null &&
            (relation.getPriorityLevel() < 1 || relation.getPriorityLevel() > 3)) {
            throw new RuntimeException("优先级必须在1-3之间");
        }

        if (relation.getEffectiveDate() != null && relation.getExpireDate() != null &&
            relation.getEffectiveDate().after(relation.getExpireDate())) {
            throw new RuntimeException("生效日期不能晚于失效日期");
        }
    }

    /**
     * 检查关联关系是否已存在
     */
    private boolean isRelationExists(Long bomId, Long projectId, Integer relationType) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", bomId)
            .eq("project_id", projectId)
            .eq("relation_type", relationType)
            .isNull("expire_date"); // 只检查未失效的关联

        return this.count(wrapper) > 0;
    }

    /**
     * 获取关联类型名称
     */
    public String getRelationTypeName(Integer relationType) {
        switch (relationType) {
            case 1: return "主要BOM";
            case 2: return "备用BOM";
            case 3: return "参考BOM";
            default: return "未知类型";
        }
    }

    /**
     * 获取优先级名称
     */
    public String getPriorityLevelName(Integer priorityLevel) {
        switch (priorityLevel) {
            case 1: return "高";
            case 2: return "中";
            case 3: return "低";
            default: return "未知优先级";
        }
    }

    /**
     * 根据使用场景查询关联关系
     */
    public List<BomProjectRelation> getRelationsByUsageScenario(String usageScenario) {
        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.like("usage_scenario", usageScenario)
            .orderByDesc("create_time");
        return this.list(wrapper);
    }

    /**
     * 获取即将失效的关联关系（用于预警）
     */
    public List<BomProjectRelation> getExpiringRelations(int daysAhead) {
        Date futureDate = new Date(System.currentTimeMillis() + daysAhead * 24 * 60 * 60 * 1000L);

        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.isNotNull("expire_date")
            .le("expire_date", futureDate)
            .gt("expire_date", new Date()) // 还未失效
            .orderBy(true, true, "expire_date");

        return this.list(wrapper);
    }

    /**
     * 复制BOM项目关联关系（用于BOM复制）
     */
    @Transactional
    public void copyBomProjectRelations(Long sourceBomId, Long targetBomId) {
        log.info("复制BOM项目关联关系: sourceBomId={}, targetBomId={}", sourceBomId, targetBomId);

        QueryWrapper<BomProjectRelation> wrapper = new QueryWrapper<>();
        wrapper.eq("bom_id", sourceBomId);

        List<BomProjectRelation> sourceRelations = this.list(wrapper);

        for (BomProjectRelation sourceRelation : sourceRelations) {
            BomProjectRelation targetRelation = new BomProjectRelation();

            // 复制字段
            targetRelation.setBomId(targetBomId);
            targetRelation.setProjectId(sourceRelation.getProjectId());
            targetRelation.setProjectName(sourceRelation.getProjectName());
            targetRelation.setRelationType(sourceRelation.getRelationType());
            targetRelation.setUsageScenario(sourceRelation.getUsageScenario());
            targetRelation.setPriorityLevel(sourceRelation.getPriorityLevel());
            targetRelation.setEffectiveDate(new Date()); // 设置为当前日期
            // 不复制失效日期
            targetRelation.setCreateTime(new Date());

            this.save(targetRelation);
        }

        log.info("BOM项目关联关系复制完成，共复制{}条记录", sourceRelations.size());
    }

    /**
     * 更新或插入项目关联关系
     */
    @Transactional
    public void upsertProjectRelation(BomMaster bomMaster, BomCreationRequest request) {
        log.info("更新项目关联关系: bomId={}, projectId={}", bomMaster.getId(), request.getProjectId());

        // 查询现有关联关系
        LambdaQueryWrapper<BomProjectRelation> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(BomProjectRelation::getBomId, bomMaster.getId())
            .eq(BomProjectRelation::getRelationType, 1); // 主要BOM关系

        BomProjectRelation existing = this.getOne(wrapper);

        if (existing != null) {
            // 更新现有关系
            existing.setProjectId(request.getProjectId());
            existing.setProjectName(request.getProjectName());
            existing.setSolutionId(request.getSolutionId());
            existing.setSolutionName(request.getSolutionName());
            existing.setUpdateTime(new Date());

            this.updateById(existing);
            log.info("项目关联关系更新成功: relationId={}", existing.getId());
        } else {
            // 创建新关系
            BomProjectRelation projectRelation = new BomProjectRelation();
            projectRelation.setBomId(bomMaster.getId());
            projectRelation.setProjectId(request.getProjectId());
            projectRelation.setProjectName(request.getProjectName());
            projectRelation.setRelationType(1); // 主要BOM
            projectRelation.setUsageScenario("设计阶段主要BOM");
            projectRelation.setPriorityLevel(1); // 高优先级
            projectRelation.setSolutionId(request.getSolutionId());
            projectRelation.setSolutionName(request.getSolutionName());
            projectRelation.setCreateTime(new Date());

            this.save(projectRelation);
            log.info("项目关联关系创建成功: relationId={}", projectRelation.getId());
        }
    }
}
